﻿using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using ViewROI;
using Brushes = System.Windows.Media.Brushes;
using Color = System.Windows.Media.Color;
using Point = System.Windows.Point;

namespace ROIWindows
{
    public class GeometryPaint
    {
        Canvas canvas = null;
        public GeometryPaint(Canvas can, Bitmap bmp)
        {
            canvas = can;
         
        }
        public void DrawAffineRectangle(Point[] affineRect)
        {
            // Create a path to draw a geometry with.
            Path myPath = new Path();
            //myPath.Stroke = Brushes.ForestGreen;
            myPath.Stroke = SystemSet.color;
            myPath.StrokeThickness = 1;

            // Create a StreamGeometry to use to specify myPath.
            StreamGeometry geometry = new StreamGeometry();
            geometry.FillRule = FillRule.EvenOdd;

            // Open a StreamGeometryContext that can be used to describe this StreamGeometry 
            // object's contents.
            using (StreamGeometryContext ctx = geometry.Open())
            {

                // Begin the triangle at the point specified. Notice that the shape is set to 
                // be closed so only two lines need to be specified below to make the triangle.
                ctx.BeginFigure(affineRect[0], true /* is filled */, true /* is closed */);

                // Draw a line to the next specified point.
                ctx.LineTo(affineRect[1], true /* is stroked */, false /* is smooth join */);

                // Draw another line to the next specified point.
                ctx.LineTo(affineRect[2], true /* is stroked */, false /* is smooth join */);

                // Draw another line to the next specified point.
                ctx.LineTo(affineRect[3], true /* is stroked */, false /* is smooth join */);
            }

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            geometry.Freeze();

            // Specify the shape (triangle) of the Path using the StreamGeometry.
            myPath.Data = geometry;

            canvas.Children.Add(myPath);
        }

        public void DrawCircle(List<double> circlePara)
        {
            const int PosCount = 50;

            Point[] points = new Point[PosCount];
            float midC = (float)circlePara[0];
            float midR = (float)circlePara[1];
            float radiusX = (float)circlePara[2];

            //double radiusY = radiusX * canvas.ActualWidth / canvas.ActualHeight;
            double radiusY = radiusX;

            float delta = 2.0f * (float)Math.PI / PosCount;

            for (int i = 0; i < PosCount; i++)
            {

                points[i].X = midC + radiusX * (float)Math.Cos(delta * i);
                points[i].Y = midR + radiusY * (float)Math.Sin(delta * i);
            }

            Path myPath = new Path();
            myPath.Stroke = Brushes.ForestGreen;
            myPath.StrokeThickness = 1;

            // Create a StreamGeometry to use to specify myPath.
            StreamGeometry geometry = new StreamGeometry();
            geometry.FillRule = FillRule.EvenOdd;

            // Open a StreamGeometryContext that can be used to describe this StreamGeometry 
            // object's contents.
         
            using (StreamGeometryContext ctx = geometry.Open())
            {
                ctx.BeginFigure(points[0], true /* is filled */, true /* is closed */);
                for (int i = 1; i < PosCount - 1; i++)
                {
                    // Begin the triangle at the point specified. Notice that the shape is set to 
                    // be closed so only two lines need to be specified below to make the triangle.
                
                    // Draw a line to the next specified point.
                    ctx.LineTo(points[i], true /* is stroked */, false /* is smooth join */);

                }             
            }

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            geometry.Freeze();

            // Specify the shape (triangle) of the Path using the StreamGeometry.
            myPath.Data = geometry;

            canvas.Children.Add(myPath);
        }

        public void DrawRectangle1(List<double> rectangle1Para)
        {
            Point pt1 = new Point() { X = rectangle1Para[0], Y = rectangle1Para[1] };
            Point pt2 = new Point() { X = rectangle1Para[0], Y = rectangle1Para[3] };
            Point pt3 = new Point() { X = rectangle1Para[2], Y = rectangle1Para[3] };
            Point pt4 = new Point() { X = rectangle1Para[2], Y = rectangle1Para[1] };


            Path myPath = new Path();
            myPath.Stroke = Brushes.ForestGreen;
            myPath.StrokeThickness = 1;

            // Create a StreamGeometry to use to specify myPath.
            StreamGeometry geometry = new StreamGeometry();
            geometry.FillRule = FillRule.EvenOdd;

            // Open a StreamGeometryContext that can be used to describe this StreamGeometry 
            // object's contents.
            using (StreamGeometryContext ctx = geometry.Open())
            {

                // Draw another line to the next specified point.
                ctx.BeginFigure(pt1, true /* is filled */, true /* is closed */);

                // Draw another line to the next specified point.
                ctx.LineTo(pt2, true /* is stroked */, false /* is smooth join */);

                ctx.LineTo(pt3, true /* is stroked */, false /* is smooth join */);

                ctx.LineTo(pt4, true /* is stroked */, false /* is smooth join */);
            }

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            geometry.Freeze();

            // Specify the shape (triangle) of the Path using the StreamGeometry.
            myPath.Data = geometry;

            canvas.Children.Add(myPath);
        }

        public void DrawLine(List<double> linePara)
        {
            Point pt1 = new Point() { X = linePara[0], Y = linePara[1] };
            Point pt2 = new Point() { X = linePara[2], Y = linePara[3] };

            Path myPath = new Path();
            myPath.Stroke = Brushes.ForestGreen;
            myPath.StrokeThickness = 1;

            // Create a StreamGeometry to use to specify myPath.
            StreamGeometry geometry = new StreamGeometry();
            geometry.FillRule = FillRule.EvenOdd;

            // Open a StreamGeometryContext that can be used to describe this StreamGeometry 
            // object's contents.
            using (StreamGeometryContext ctx = geometry.Open())
            {

                // Draw another line to the next specified point.
                ctx.BeginFigure(pt1, true /* is filled */, true /* is closed */);

                // Draw another line to the next specified point.
                ctx.LineTo(pt2, true /* is stroked */, false /* is smooth join */);
            }

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            geometry.Freeze();

            // Specify the shape (triangle) of the Path using the StreamGeometry.
            myPath.Data = geometry;

            canvas.Children.Add(myPath);
        }

        public void DrawArrow(double x1, double y1, double x2, double y2, double ArrowLengh)
        {
            Path arrowPath = new Path();
            arrowPath.Stroke = Brushes.Pink;
            arrowPath.StrokeThickness = 1;

            Point point = new Point(x1, y1);
            Point point2 = new Point(x2, y2);
            double num = Math.Atan((y2 - y1) / (x2 - x1));
            double ArrowAngle = 0.18;
            double d = num - ArrowAngle;
            double num3 = num + ArrowAngle;
            int num4 = (x2 > x1) ? -1 : 1;
            double x = x2 + ((num4 * ArrowLengh) * Math.Cos(d));
            double y = y2 + ((num4 * ArrowLengh) * Math.Sin(d));
            double num7 = x2 + ((num4 * ArrowLengh) * Math.Cos(num3));
            double num8 = y2 + ((num4 * ArrowLengh) * Math.Sin(num3));
            Point point3 = new Point(x, y);
            Point point4 = new Point(num7, num8);
            if (x1 == x2)
            {
                point3.Y = (point2.Y * 2 - point3.Y);
                point4.Y = (point2.Y * 2 - point4.Y);
            }
            PathGeometry geometry = new PathGeometry();
            PathFigure figure = new PathFigure();
            figure.IsFilled = true;
            figure.StartPoint = point2;
            Point[] points = new Point[] { point, point2, point3, point4, point2 };//从point2到point 然后在倒回来到point2，然后画箭头。及从point2到point3到point4到point2.....
            PolyLineSegment segment = new PolyLineSegment(points, true);
            figure.Segments.Add(segment);
            geometry.Figures.Add(figure);
            geometry.Freeze();
            arrowPath.Data = geometry;

            canvas.Children.Add(arrowPath);
        }

        public void DrawMouseCoord(int i)
        {
            TextBlock tb = new TextBlock();
            Canvas.SetLeft(tb, 32);
            Canvas.SetBottom(tb, 21);
            tb.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            tb.FontSize = 50;
            tb.Text = string.Format("{0}", i);
            canvas.Children.Add(tb);
        }    
    }
}
